package com.douqu.game.main.msg;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bean.core.buffer.ByteBuffer;
import com.bean.core.util.TimeUtils;
import com.bean.core.util.Utils;
import com.douqu.game.core.config.challenge.WorldBossConfig;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.database.model.GMModel;
import com.douqu.game.core.database.model.PlayerModel;
import com.douqu.game.core.database.model.ServerModel;
import com.douqu.game.core.database.model.UpdateConfigModel;
import com.douqu.game.core.e.E_GMType;
import com.douqu.game.core.e.E_NoticeType;
import com.douqu.game.core.e.E_UpdateConfigType;
import com.douqu.game.core.entity.GMSetting;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.db.MailDB;
import com.douqu.game.core.entity.ext.MailInfo;
import com.douqu.game.core.entity.world.WorldArenaData;
import com.douqu.game.core.entity.world.WorldBossData;
import com.douqu.game.core.entity.world.WorldRankBean;
import com.douqu.game.core.entity.world.WorldRankData;
import com.douqu.game.core.factory.*;
import com.douqu.game.core.netty.NettyConnection;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.protobuf.SGSystemProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.HotUpdateUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.SendUtils;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.database.mapper.read.ReadPlayerMapper;
import com.douqu.game.main.database.mapper.write.WriteServerMapper;
import com.douqu.game.main.server.*;
import com.douqu.game.main.server.entity.MailGroup;
import com.douqu.game.main.server.entity.NoticeInfo;
import com.douqu.game.main.service.PlayerService;
import com.douqu.game.main.service.WorldService;
import com.douqu.game.main.util.CosUtils;
import com.douqu.game.main.util.MsgUtils;
import com.douqu.game.main.util.RobotCreateHelper;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2018-10-18 10:55
 */
public class GMSystemChannel {

    public static void messageChannel(int code, NettyConnection connection, ByteBuffer data) throws Exception
    {
        switch (code)
        {
            case CodeFactory.GM_SYSTEM_NOTICE_SEND:
                sendNotice(connection, data, code);
                break;
            case CodeFactory.GM_SYSTEM_NOTICE_LIST:
                getNoticeList(connection, code);
                break;
            case CodeFactory.GM_SYSTEM_NOTICE_DEL:
                delNotice(connection, data, code);
                break;
            case CodeFactory.GM_SYSTEM_MAIL_GROUP:
                groupMail(connection, data, code);
                break;
            case CodeFactory.GM_SYSTEM_OBJECT_CONFIG:
                updateConfig(connection, data, code, false);
                break;
            case CodeFactory.GM_SYSTEM_SERVER_CONFIG:
                updateServerConfig(connection, data, code);
                break;
            case CodeFactory.GM_SYSTEM_OTHER_CONFIG:
                updateOtherConfig(connection, data, code);
                break;
            case CodeFactory.GM_SYSTEM_SERVER_LIST:
                break;
            case CodeFactory.GM_SYSTEM_SERVER_TEST:
                break;
            case CodeFactory.GM_SYSTEM_SUPER_CMD:
                superCmd(connection, data, code);
                break;
            case CodeFactory.GM_SYSTEM_CHAT:
                sendChat(connection, data, code);
                break;
            case CodeFactory.GM_SYSTEM_PLATFORM:
                platformProcess(connection, data, code);
                break;
            case CodeFactory.GM_SYSTEM_FIX_ROBOT:
                fixRobot(connection, data, code);
                break;
            case CodeFactory.GM_SYSTEM_CHECK_CAMP:
                checkCamp(connection, code);
                break;
            case CodeFactory.GM_SYSTEM_LOCAL_CONFIG:
                updateConfig(connection, data, code, true);
                break;
            case CodeFactory.GM_SYSTEM_CONFIG_TASK:
                configTask(connection, data, code);
                break;
        }
    }

    private static void configTask(NettyConnection connection, ByteBuffer data, int code)
    {
        boolean isUpdate = data.available() > 0 ? data.readBoolean() : false;
        if(isUpdate)
        {
            //更新或添加
            String content = data.readUTF();
            UpdateConfigModel model = JSONObject.parseObject(content, UpdateConfigModel.class);
            if(Utils.isNullOrEmpty(model.getVersion()) || Utils.isNullOrEmpty(model.getBucket()) || Utils.isNullOrEmpty(model.getPath()))
            {
                GMChannel.sendError(connection, "参数错误");
                return;
            }

            if(model.getStartTime().getTime() <= DataFactory.currentTime)
            {
                GMChannel.sendError(connection, "任务开始时间不能比当前时间早");
                return;
            }

            if(model.getId() == 0 && UpdateManager.getInstance().isExistConfigByVersion(model.getVersion()))
            {
                GMChannel.sendError(connection, "请不要添加相同的任务");
                return;
            }

            E_UpdateConfigType type = SpringContext.isDev() ? E_UpdateConfigType.LOCAL : E_UpdateConfigType.REMOTE;
            model.setType(type.name());

            try{
                if(!UpdateManager.getInstance().downloadConfigFile(model, PlatformFactory.CONFIG_PATH + model.getVersion()))
                {
                    GMChannel.sendError(connection, "网络异常或文件目录不存在,请检查");
                    return;
                }
            }catch (Exception e){
                LogUtils.errorException(e);
            }


            List<String> errorList = UpdateManager.getInstance().testConfig(PlatformFactory.CONFIG_PATH + model.getVersion());
            if(!errorList.isEmpty())
            {
                GMChannel.sendError(connection, "版本" + model.getVersion() + "里的配置文件有错，请检查 -> \n" + errorList.get(0));
                return;
            }

            if(model.getId() == 0)
            {
                GMModel gmModel = (GMModel) connection.getObject();
                model.setOptionPerson(gmModel.getUsername());
                model.setCreateTime(new Date());
                //新增
                UpdateManager.getInstance().addConfigTask(model);

                GMChannel.saveGMLog(connection, null, "创建定时更新任务,version->" + model.getVersion(), code, JSONObject.toJSONString(model));
            }
            else
            {
                UpdateConfigModel oldModel = UpdateManager.getInstance().getConfigTask(model);
                if(oldModel != null)
                {
                    GMChannel.saveGMLog(connection, null, "更新定时更新任务,version FROM " + oldModel.getVersion() + " TO " + model.getVersion(), code, JSONObject.toJSONString(model));

                    oldModel.setType(model.getType());
                    oldModel.setStartTime(model.getStartTime());
                    oldModel.setVersion(model.getVersion());
                    oldModel.setBucket(model.getBucket());
                    oldModel.setPath(model.getPath());
                    UpdateManager.getInstance().updateConfigTask(oldModel);
                }
                else
                {
                    GMChannel.sendError(connection, "要更新的任务不存在");
                    return;
                }
            }
        }

        List<UpdateConfigModel> list = UpdateManager.getInstance().getConfigTaskList();
        JSONArray jsonArray = new JSONArray();
        for(UpdateConfigModel model : list)
        {
            jsonArray.add(JSONObject.toJSON(model));
        }

        ByteBuffer out = new ByteBuffer();
        out.writeBoolean(isUpdate);
        out.writeUTF(jsonArray.toJSONString());
        connection.sendMsg(code, out.getBytes());

    }



    private static void fixRobot(NettyConnection connection, ByteBuffer data, int code)
    {
        ReadPlayerMapper playerMapper = SpringContext.getBean(ReadPlayerMapper.class);
        int robotCount = playerMapper.findRobotCount();
        if(robotCount == 0)
        {
            GMChannel.sendError(connection, "请先创建机器人!");
        }
        else
        {
            List<PlayerModel> robotList = playerMapper.findAllRobot();

            WorldArenaData worldArenaData = WorldInfoFactory.getInstance().getArenaRankInfo();
            WorldRankData worldRankData = WorldInfoFactory.getInstance().getWorldRankData();
            boolean clearArena = data.readBoolean();
            if(clearArena)
                worldArenaData.clear();

            for(PlayerModel robot : robotList)
            {
                worldRankData.updateRankInfo(SGCommonProto.E_RANK_TYPE.RANK_TYPE_FC, robot.getObjectIndex(), robot.getFc());

                worldArenaData.getArenaRankByObjectIndex(robot.getObjectIndex());
            }

            List<WorldRankBean> list = worldRankData.getRankList(SGCommonProto.E_RANK_TYPE.RANK_TYPE_FC);
            int index = -1;
            for(WorldRankBean bean : list)
            {
                index = robotList.indexOf(new PlayerModel(bean.getObjectIndex()));
                if(index != -1)
                {
                    GameServer.getInstance().getWorldManager().updateRankPlayerDetail(robotList.get(index));
                }
            }

            connection.sendMsg(code);
        }
    }
    private static void checkCamp(NettyConnection connection, int code)
    {
        if(ServerManager.getInstance().getActivityServer() != null)
        {
            GMChannel.sendError(connection, "阵营战服务器连接正常");
        }
        else
        {
            boolean result = GameServer.getInstance().notifyActivityServer();
            if(!result)
            {
                GMChannel.sendError(connection, "服务器状态异常，请检查阵营战服务器是否开启或者当前服务器是否加入了阵营战");
            }
            else
            {
                connection.sendMsg(code);
            }
        }
    }



    private static void sendChat(NettyConnection connection, ByteBuffer data, int code) {
        String content = data.readUTF();
        content = content.replaceAll(" ", "");
        if (CoreUtils.isNullOrEmpty(content) || content.length() > 100) {
            GMChannel.sendError(connection, "内容长度错误(1-100)");
            return;
        }

        MsgUtils.sendChat("GM管理员", content, SGCommonProto.E_CHAT_TYPE.CHAT_TYPE_SYSTEM);

        connection.sendMsg(code);
    }


    private static void platformProcess(NettyConnection connection, ByteBuffer data, int code)
    {
        String type = data.readUTF();
        JSONObject response = new JSONObject();

        switch (type)
        {
            case CodeFactory.PLATFORM_QUERY_ALL:
                break;
            case CodeFactory.PLATFORM_QUERY_TENPAY:
                response.put(PlatformFactory.KEY_TENPAY, PlatformFactory.getTenpayConfig());
                break;
            case CodeFactory.PLATFORM_QUERY_ALIPAY:
                response.put(PlatformFactory.KEY_ALIPAY, PlatformFactory.getAlipayConfig());
                break;
            case CodeFactory.PLATFORM_QUERY_OTHER:
                response.put(PlatformFactory.KEY_OTHER, PlatformFactory.getOtherConfig());
                break;
            case CodeFactory.PLATFORM_UPDATE_ALL:
                break;
            case CodeFactory.PLATFORM_UPDATE_TENPAY:
                if(!GameServer.getInstance().getPlatformConfigFromAuth(PlatformFactory.KEY_TENPAY))
                {
                    GMChannel.sendError(connection, "从认证服务器获取微信支付配置错误!");
                    return;
                }
                response.put(PlatformFactory.KEY_TENPAY, PlatformFactory.getTenpayConfig());
                break;
            case CodeFactory.PLATFORM_UPDATE_ALIPAY:
                if(!GameServer.getInstance().getPlatformConfigFromAuth(PlatformFactory.KEY_ALIPAY))
                {
                    GMChannel.sendError(connection, "从认证服务器获取支付宝支付配置错误!");
                    return;
                }
                response.put(PlatformFactory.KEY_ALIPAY, PlatformFactory.getAlipayConfig());
                break;
            case CodeFactory.PLATFORM_UPDATE_OTHER:
                if(!GameServer.getInstance().getPlatformConfigFromAuth(PlatformFactory.KEY_OTHER))
                {
                    GMChannel.sendError(connection, "从认证服务器获取平台配置错误!");
                    return;
                }
                response.put(PlatformFactory.KEY_OTHER, PlatformFactory.getOtherConfig());
                break;
            default:
                GMChannel.sendError(connection, "参数错误->" + type);
                return;
        }

        ByteBuffer out = new ByteBuffer();
        out.writeUTF(response.toJSONString());
        connection.sendMsg(code, out.getBytes());
    }

    private static void superCmd(NettyConnection connection, ByteBuffer data, int code)
    {
        String cmd = data.readUTF();

        if (CodeFactory.CMD_CREATE_ROBOT.equals(cmd)) {
            ReadPlayerMapper playerMapper = SpringContext.getBean(ReadPlayerMapper.class);
            int robotCount = playerMapper.findRobotCount();
            int count = data.available() > 0 ? data.readInt() : 2000;
            if(robotCount >= count)
            {
                GMChannel.sendError(connection, "已经创建过机器人了");
                return;
            }
            createRobot(connection, count, code);
        }
        else if (CodeFactory.CMD_CREATE_BOSS.equals(cmd)) {
            int bossId = createBoss(connection);
            if (bossId != 0) {
                connection.sendMsg(code);

                GMChannel.saveGMLog(connection, null, "创建世界BOSS -> " + bossId, code, bossId + "");
            }
        }
        else if(CodeFactory.CMD_UPDATE_CLASS.equals(cmd))
        {
            //热更新服务器,只能修改方法内部的逻辑,不能修改方法名,方法参数类型,个数,也不能添加删除方法,服务器重启时请记得重新打新的包
            String path = data.available() > 0 ? data.readUTF() : HotUpdateUtils.PATH;
            File file = HotUpdateUtils.checkDirectory(path);
            if(file == null)
            {
                GMChannel.sendError(connection, "不是目录或者目录不存在,请检查 -> " + CoreUtils.getBasePath() + path);
                return;
            }
            LogUtils.warn("热更新  path -> " + path);

            LoadManager.updating = true;

            HotUpdateUtils.updateClass(file, "com.douqu.game.battle");

            ServerManager.getInstance().sendUpdateClass(path);

            GMChannel.saveGMLog(connection, null, "热更新代码 -> " + path, code, path);

            LoadManager.updating = false;

            connection.sendMsg(code);
        }
        else if(CodeFactory.CMD_UPDATE_WHITE.equals(cmd))
        {
            LogUtils.warn("更新白名单");
            GameServer.getInstance().getWorldManager().updateWhite();
            connection.sendMsg(code);
        }
        else
        {
            GMChannel.sendError(connection, "指令错误 -> " + cmd);
        }
    }



    private static int createBoss(NettyConnection connection) {
        WorldBossData bossData = WorldInfoFactory.getInstance().getWorldBossData();
        if (bossData.isCanCreeateBoss()) {
            // 测试
            PlayerService playerService = SpringContext.getBean(PlayerService.class);
            List<WorldBossConfig> configs = DataFactory.getInstance().getDataList(DataFactory.WORLD_BOSS_KEY);
            int averageLv = playerService.getWorldPlayerAverageLevel(10,
                    FunctionFactory.WORLD_BOSS);
            for (WorldBossConfig config : configs) {
                //0816线上版本
//				int id = StringUtils.isNullOrEmpty(bossData.getBossInfo().getIndexInfo()) ? 0
//						: Integer.valueOf(bossData.getBossInfo().getIndexInfo());
//				if (config.id > id) {
                ////////////////////////////////////
                //0816修改后版本
                int id = CoreUtils.getCurrentBossId();
                if (config.id == id) {
                    ///////////////////////////////
                    bossData.createNewBoss(config.id, averageLv);
                    GameServer.getInstance().getWorldManager()
                            .addNotice(new NoticeInfo(WordFactory.getWord(WordFactory.BOSS_FRESH_NOTICE, config.name),
                                    5, 10, "system", DataFactory.currentTime,E_NoticeType.NOTICE_TYPE_BOSS));
                    WorldRankData rankData = WorldInfoFactory.getInstance().getWorldRankData();
                    RecordManager.getInstance().addLastRankMap(SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS, rankData.getRankList(SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS));
                    rankData.clearRank(SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS);
                    return config.id;
                }
            }

            GameServer.getInstance().getWorldManager()
                    .addNotice(new NoticeInfo(WordFactory.getWord(WordFactory.BOSS_FRESH_NOTICE, configs.get(0).name),
                            5, 10, "system", DataFactory.currentTime,E_NoticeType.NOTICE_TYPE_BOSS));
            bossData.createNewBoss(configs.get(0).id, averageLv);
            //bossData.getHasKillBoss().clear();
            //创建boss成功后要更新排行榜
            WorldRankData rankData = WorldInfoFactory.getInstance().getWorldRankData();
            RecordManager.getInstance().addLastRankMap(SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS, rankData.getRankList(SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS));
            rankData.clearRank(SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS);
            return configs.get(0).id;
        } else {
            GMChannel.sendError(connection, "已有存活BOSS");
            return 0;
        }
    }


    /**
     * 创建机器人玩家并加入竞技场
     *
     * @param connection
     */
    public static void createRobot(NettyConnection connection, int robotCount, int code)
    {
        ReadPlayerMapper playerMapper = SpringContext.getBean(ReadPlayerMapper.class);
        int totalCount = playerMapper.findRobotCount();
        // robotCount = robotCount < 1000 ? 1000 : robotCount;
        robotCount = robotCount > 5000 ? 5000 : robotCount;
        if (totalCount < robotCount) {
            WorldService worldService = SpringContext.getBean(WorldService.class);
            WorldInfoFactory.getInstance().load(worldService.find());

            for (int i = 0; i < robotCount - totalCount; i++)
            {
                PlayerModel playerModel = RobotCreateHelper.getInstance().createPlayerByArenaPosition(i);

                RobotCreateHelper.getInstance().appendToArenaWorldRank(playerModel.getObjectIndex());

                GameServer.getInstance().getWorldManager().updateRankInfo(SGCommonProto.E_RANK_TYPE.RANK_TYPE_FC, playerModel, playerModel.getFc());

                GMChannel.savePlayerModel(playerModel);

                LogUtils.info("生成机器人 -> " + playerModel.getName());
            }

            WorldInfoFactory.getInstance().getWorldCollectData().init();

            LogUtils.warn("生成2000个机器人成功------------->");

            worldService.update();

            GMChannel.saveGMLog(connection, null, "生成机器人", code, "createRobot");

            if (connection != null) {
                connection.sendMsg(code);
            }
        } else {
            if (connection != null) {
                GMChannel.sendError(connection, "已经生成过机器人了");
            }
        }

    }



    private static void groupMail(NettyConnection connection, ByteBuffer data, int code)
    {
        if (data.available() == 0)// 表示获取发送列表
        {
            List<MailGroup> list = GameServer.getInstance().getWorldManager().getMailGroupList();
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = null;
            for (MailGroup mailGroup : list) {
                jsonObject = new JSONObject();
                jsonObject.put("camp", mailGroup.getCamp());
                jsonObject.put("minLevel", mailGroup.getMinLevel());
                jsonObject.put("maxLevel", mailGroup.getMaxLevel());
                jsonObject.put("title", mailGroup.getMail().getTitle());
                jsonObject.put("attach", mailGroup.getMail().getAttachStr());
                jsonObject.put("createTime", mailGroup.getMail().getCreateTime());
                jsonObject.put("lastLoginDays", mailGroup.getLastLoginDays());
                jsonArray.add(jsonObject);
            }
            ByteBuffer out = new ByteBuffer(Integer.MAX_VALUE / 10);
            out.writeUTF(jsonArray.toJSONString());
            connection.sendMsg(code, out.getBytes());
            return;
        }

        GMModel gmModel = (GMModel) connection.getObject();
        if (gmModel.getType() != E_GMType.SUPER.getCode() && gmModel.getType() != E_GMType.ADMIN.getCode()) {
            GMChannel.sendError(connection, "你没有权限操作此功能");
            return;
        }

        MailGroup mailGroup = JSON.parseObject(data.readUTF(), MailGroup.class);
        LogUtils.debug("群发邮件 -> " + mailGroup);

        if (!mailGroup.check()) {
            GMChannel.sendError(connection, "参数错误 -> " + mailGroup);
            return;
        }


        List<GoodsData> attachList = new CopyOnWriteArrayList<>();
        for (GoodsData goodsData : mailGroup.getMail().getAttachArray()) {
            if (!goodsData.checkGoods()) {
                GMChannel.sendError(connection, "附件参数错误 -> id:" + goodsData.id + " count:" + goodsData.value);
                return;
            }
            attachList.add(goodsData);
        }

        PlayerService playerService = SpringContext.getBean(PlayerService.class);
        List<PlayerModel> playerModelList = null;
        if(!mailGroup.isFixedPlayer())
        {
            int camp = mailGroup.getCamp();
            int minLevel = mailGroup.getMinLevel();
            int maxLevel = mailGroup.getMaxLevel();
            int lastLoginDays = mailGroup.getLastLoginDays();

            playerModelList = playerService.findListByGroupMail(camp, minLevel, maxLevel, lastLoginDays);
            if (playerModelList.isEmpty()) {
                GMChannel.sendError(connection, "此区间没有玩家");
                return;
            }

            sendGroupMail(mailGroup, attachList, playerModelList);

            GMChannel.saveGMLog(connection, null,
                    "给定范围群发邮件,标题:" + mailGroup.getMail().getTitle() + "," + "玩家范围:等级区间[" + minLevel + "-"
                            + (maxLevel == 0 ? "不限" : maxLevel) + "],阵营->" + (camp == 0 ? "全部" : camp),
                    code, camp + ":" + minLevel + ":" + maxLevel);
        }
        else
        {
            if(mailGroup.getPlayerNameList() == null || mailGroup.getPlayerNameList().isEmpty())
            {
                GMChannel.sendError(connection, "玩家列表为空");
                return;
            }

            playerModelList = playerService.getPlayerListByName(mailGroup.getPlayerNameList());
            if (playerModelList.isEmpty()) {
                GMChannel.sendError(connection, "玩家昵称错误");
                return;
            }

            sendGroupMail(mailGroup, attachList, playerModelList);

            StringBuilder str = new StringBuilder();
            for(PlayerModel playerModel : playerModelList)
            {
                str.append(playerModel.getName());
                str.append(",");
            }

            GMChannel.saveGMLog(connection, null, "指定玩家群发邮件,标题:" + mailGroup.getMail().getTitle() + ", 玩家数量:" + playerModelList.size(), code, str.substring(0, str.length() - 1));
        }

        ByteBuffer out = new ByteBuffer();
        out.writeBoolean(mailGroup.isFixedPlayer());
        connection.sendMsg(code, out.getBytes());
    }

    private static MailDB sendGroupMail(MailGroup mailGroup, List<GoodsData> attachList, List<PlayerModel> playerModelList)
    {
        List<Player> offlineList = new ArrayList<>();
        MailDB mailDB = null;
        for (PlayerModel playerModel : playerModelList) {
            mailDB = new MailDB();
            mailDB.title = mailGroup.getMail().getTitle();
            mailDB.content = mailGroup.getMail().getContent();
            mailDB.roleType = SGCommonProto.E_MAIL_SENDER_TYPE.MAIL_SENDER_TYPE_RECEIVER_VALUE;
            mailDB.sendTime = DataFactory.currentTime;
            mailDB.target = "-1";
            mailDB.setAttachList(attachList);

            sendSingleMail(playerModel, mailDB, offlineList);

            LogUtils.debug("群发邮件 -> " + playerModel.getName());
        }

        if (offlineList.size() > 0) {
            GMChannel.updatePlayers(offlineList, false, MailInfo.class);
        }

        GameServer.getInstance().getWorldManager().addGroupMail(mailGroup);

        return mailDB;
    }

    private static void sendSingleMail(PlayerModel playerModel, MailDB mailDB, List<Player> offlineList) {
        MailInfo mailInfo = null;

        PlayerController playerController = GameServer.getInstance().getWorldManager()
                .getPlayerController(playerModel.getObjectIndex());
        if (playerController != null)// 在线
        {
            mailInfo = playerController.getPlayer().getExtInfo(MailInfo.class);

            // 在线,要推送新邮件消息
            SendUtils.mailPush(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_SYSTEM, playerController);
        } else {
            Player player = new Player(playerModel);
            mailInfo = player.getExtInfo(MailInfo.class);

            offlineList.add(player);
        }

        mailInfo.addMail(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_SYSTEM_VALUE, mailDB);
    }

    private static void updateOtherConfig(NettyConnection connection, ByteBuffer data, int code)
    {
        String json = data.readUTF();

        GMSetting setting = JSON.parseObject(json, GMSetting.class);

        if (setting.getMainLog() == null || setting.getBattleLog() == null || setting.getPlayerOverdueTime() <= 0
                || setting.getPlayerWaitTime() <= 0) {
            GMChannel.sendError(connection, "参数错误");
            return;
        }

        ConfigFactory.gmSetting = setting;
        LogUtils.setLogLevel(setting.getMainLog());

        LogUtils.info("GM设置 -> " + setting);

        // GMSetting battleSetting = new GMSetting();
        // battleSetting.setPlayerOverdueTime(setting.getPlayerOverdueTime());
        // battleSetting.setPlayerWaitTime(setting.getPlayerWaitTime());
        // battleSetting.setBattleLog(setting.getBattleLog());
        // battleSetting.setMainLog(setting.getMainLog());
        // battleSetting.setLogLevel(setting.getBattleLog());
        // LogUtils.debug("设置战斗服务器配置 -> " + battleSetting);

        ServerManager.getInstance().sendUpdateLogLevel();

        ByteBuffer out = new ByteBuffer();
        out.writeUTF(json);
        connection.sendMsg(code, out.getBytes());

        GMChannel.saveGMLog(connection, null, "GMSetting", code, json);
    }

    private static void getNoticeList(NettyConnection connection, int code)
    {
        List<NoticeInfo> list = GameServer.getInstance().getWorldManager().getGmNoticeList();

        JSONObject response = new JSONObject();
        JSONArray noticeAry = new JSONArray();
        for (NoticeInfo noticeInfo : list) {
            noticeAry.add(JSONObject.toJSON(noticeInfo));
        }

        response.put("noticeList", noticeAry);

        ByteBuffer out = new ByteBuffer();
        out.writeUTF(response.toJSONString());
        connection.sendMsg(code, out.getBytes());
    }

    private static void updateServerConfig(NettyConnection connection, ByteBuffer data, int code) {
        String dataStr = data.readUTF();
        ServerModel serverModel = JSON.parseObject(dataStr, ServerModel.class);
        if (!serverModel.checkServerStatusCount()) {
            GMChannel.sendError(connection, "状态人数配置错误");
            return;
        }
        if (serverModel.getId() <= 0) {
            GMChannel.sendError(connection, "服务器ID参数错误");
            return;
        }

        // if(StringUtils.isNullOrEmpty(serverModel.getBattleServerHost())
        // || StringUtils.isNullOrEmpty(serverModel.getAuthServerHost()))
        // {
        // GMChannel.sendError(connection, "服务器地址参数错误");
        // return;
        // }

        if (serverModel.getPlayerIndex() <= 0)
            serverModel.setPlayerIndex(ConstantFactory.INIT_PLAYER_INDEX);

        WriteServerMapper writeServerMapper = SpringContext.getBean(WriteServerMapper.class);
        int result = writeServerMapper.update(serverModel);
        if (result == 0) {
            serverModel.setCreateTime(TimeUtils.getCurrentDate());
            writeServerMapper.create(serverModel);
        }
        GameServer.getInstance().getWorldManager().load(serverModel);

        ByteBuffer out = new ByteBuffer();
        out.writeUTF(JSONObject.toJSONString(serverModel));
        connection.sendMsg(code, out.getBytes());

        GMChannel.saveGMLog(connection, null, "设置系统配置", code, dataStr);
    }

    private static void updateConfig(NettyConnection connection, ByteBuffer data, int code, boolean localUpdate)
    {
        if(LoadManager.loading)
        {
            GMChannel.sendError(connection, "正在更新配置文件");
            return;
        }

        if (DataFactory.currentTime - LoadManager.lastUpdateTime <= 30000) {
            GMChannel.sendError(connection, "更新最小间隔时间为1分钟!");
            return;
        }

        String path = data.readUTF();// 路径
        String version = data.readUTF();// 版本
        String bucket = data.readUTF();//bucket 外网才有的
        boolean updateActivity = false;
        if(data.available() > 0)
        {
            updateActivity = data.readBoolean();
        }

        if (Utils.isNullOrEmpty(path) || Utils.isNullOrEmpty(version))
        {
            GMChannel.sendError(connection, "参数错误");
            return;
        }

        if(GameServer.getInstance().getVersion().equals(version))
        {
            GMChannel.sendError(connection, "更新的版本跟服务器当前版本相同");
            return;
        }

        if(localUpdate)
        {
            LogUtils.warn("更新本地配置文件,path -> " + path);

            boolean result = CosUtils.copyLocalFile(path, PlatformFactory.CONFIG_PATH);
            if (!result)
            {
                GMChannel.sendError(connection, "网络异常或文件目录不存在,请检查");
                return;
            }
        }
        else
        {
            if(!Utils.isNullOrEmpty(bucket)) PlatformFactory.TENCENT_COS_BUCKET = bucket;

            LogUtils.warn("更新配置文件,BUCKET -> " + PlatformFactory.TENCENT_COS_BUCKET);

            boolean result = CosUtils.downloadFile(PlatformFactory.TENCENT_COS_BUCKET, path, PlatformFactory.CONFIG_PATH);
            if (!result)
            {
                GMChannel.sendError(connection, "网络异常或文件目录不存在,请检查");
                return;
            }
        }

        connection.setLastUpdateConfigTime(DataFactory.currentTime);

        LoadFactory.setTestLoad(true);

        LoadManager.testLoad(PlatformFactory.CONFIG_PATH);

        List<String> errorList = DataFactory.getInstance(true).getErrorList();

        LoadFactory.setTestLoad(false);

        if (errorList.isEmpty())
        {
            LogUtils.warn("GM开始更新配置文件,服务器暂停使用=========================================");

            LoadManager.GMLoad();

            ServerManager.getInstance().sendLoadData();

            GMChannel.saveGMLog(connection, null, "更新主服务器配置文件->" + version, code, "updateConfig=>" + version);

            GameServer.getInstance().notifyUpdateVersion(version);

            GameServer.getInstance().getWorldManager().dispatchMsg(SGMainProto.E_MSG_ID.MsgID_System_ConfigUpdate_VALUE,
                    SGSystemProto.S2C_ConfigUpdate.newBuilder().setVersion(version).build().toByteArray());

            if(updateActivity)
            {
                //活动服暂时不支持本地更新
                ServerManager.getInstance().sendToActivityUpdateConfig(path, version);

                GMChannel.saveGMLog(connection, null, "更新活动服务器配置文件->" + version, code, "updateConfig=>" + version);
            }

            //配置文件更新完成重新计算
            GameServer.getInstance().updateActivity();
            LogUtils.warn("更新活动大厅数据成功 ");
        }

        ByteBuffer out = new ByteBuffer();
        out.writeUTF(LoadManager.lastUpdateTime + "");

        out.writeShort(errorList.size());
        for (String error : errorList) {
            out.writeUTF(error);
        }
        connection.sendMsg(code, out.getBytes());
    }



    private static void sendNotice(NettyConnection connection, ByteBuffer data, int code) {
        String content = data.readUTF();
        content = content.replaceAll(" ", "");
        if (content.length() == 0 || content.length() > 140) {
            GMChannel.sendError(connection, "公告内容超长(1-140字)");
            return;
        }

        int times = 1, interval = 5;
        if (data.available() > 0) {
            times = data.readShort();
            times = times < 1 ? 1 : times;
            interval = data.readShort();
            interval = interval < 5 ? 5 : interval;
        }

        GameServer.getInstance().getWorldManager().addNotice(new NoticeInfo(content, times, interval,
                ((GMModel) connection.getObject()).getUsername(), DataFactory.currentTime, E_NoticeType.NOTICE_TYPE_OTHER));

        GMChannel.sendError(connection, "发送成功");

        GMChannel.saveGMLog(connection, null, "发送公告:" + content, code, "notice");

        getNoticeList(connection, CodeFactory.GM_SYSTEM_NOTICE_LIST);
    }

    private static void delNotice(NettyConnection connection, ByteBuffer data, int code)
    {
        String id = data.readUTF();

        GameServer.getInstance().getWorldManager().delNotice(id);

        getNoticeList(connection, CodeFactory.GM_SYSTEM_NOTICE_LIST);
    }
}
